using System;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.RelyingParty;
using Application.MainModule.DinnerManagement;
using Domain.MainModule.Entities;
using Presentation.Web.UI.Attibutes;
using Presentation.Web.UI.ViewModels;

namespace Presentation.Web.UI.Controllers
{
    [HandleErrorWithELMAH]
    public class RSVPController : Controller
    {
        private readonly IDinnerManagementService _dinnerService;
        private static readonly OpenIdRelyingParty RelyingParty = new OpenIdRelyingParty();

        #region Constructors
        public RSVPController(IDinnerManagementService dinnerService)
        {
            _dinnerService = dinnerService;
        }

        #endregion
        //
        // AJAX: /Dinners/Register/1
        [Authorize, HttpPost]
        public ActionResult Register(int id)
        {
            Dinners dinner = _dinnerService.FindDinner(id);
            if (!dinner.IsUserRegistered(User.Identity.Name))
            {
                var nerd = (WebIdentity)User.Identity;
                var rsvp = new RSVPs {DinnerID = dinner.DinnerID, AttendeeNameId = nerd.Name, AttendeeName = nerd.CustomerName};
                dinner.RSVPs.Add(rsvp);
                _dinnerService.InsertOrUpdateDinner(dinner);
                _dinnerService.Save();
            }
            return Content("Thanks - we'll see you there!");
        }

        //
        // AJAX: /RSVP/Cancel/1

        [Authorize, HttpPost]
        public ActionResult Cancel(int id)
        {

            Dinners dinner = _dinnerService.FindDinner(id);
            RSVPs rsvp = dinner.RSVPs.SingleOrDefault(r => User.Identity.Name == r.AttendeeNameId);

            if (rsvp != null)
            {
                _dinnerService.DeleteRSVP(rsvp);
                _dinnerService.Save();
            }

            return Content("Sorry you can't make it!");
        }

        //
        // GET: /RSVP/RsvpBegin

        public ActionResult RsvpBegin(string identifier, int id)
        {
            var returnTo = new Uri(new Uri(Realm.AutoDetect), Url.Action("RsvpFinish"));
            IAuthenticationRequest request = RelyingParty.CreateRequest(identifier, Realm.AutoDetect, returnTo);
            request.SetUntrustedCallbackArgument("DinnerId", id.ToString(CultureInfo.InvariantCulture));
            request.AddExtension(new ClaimsRequest { Email = DemandLevel.Require, FullName = DemandLevel.Request });
            return request.RedirectingResponse.AsActionResult();
        }
        //
        // GET: /RSVP/RsvpBegin
        // POST: /RSVP/RsvpBegin

        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post), ValidateInput(false)]
        public ActionResult RsvpFinish()
        {
            IAuthenticationResponse response = RelyingParty.GetResponse();
            if (response == null)
            {
                return RedirectToAction("Index");
            }

            if (response.Status == AuthenticationStatus.Authenticated)
            {
                int id = int.Parse(response.GetUntrustedCallbackArgument("DinnerId"));
                Dinners dinner = _dinnerService.FindDinner(id);

                // The alias we're getting here is NOT a secure identifier, but a friendly one,
                // which is all we need for this scenario.
                string alias = response.FriendlyIdentifierForDisplay;
                var sreg = response.GetExtension<ClaimsResponse>();
                if (sreg != null && sreg.MailAddress != null)
                {
                    alias = sreg.MailAddress.User;
                }

                // NOTE: The alias we've generated for this user isn't guaranteed to be unique.
                // Need to trim to 30 characters because that's the max for Attendee names.
                if (!dinner.IsUserRegistered(alias))
                {
                    var rsvp = new RSVPs {AttendeeName = alias, AttendeeNameId = response.ClaimedIdentifier};

                    dinner.RSVPs.Add(rsvp);
                    _dinnerService.Save();
                }
            }

            return RedirectToAction("Details", "Dinners", new { id = response.GetUntrustedCallbackArgument("DinnerId") });
        }
    }
}
